package com.joolun.mall.service.impl;

import cn.binarywang.wx.miniapp.bean.shortlink.GenerateShortLinkRequest;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.joolun.common.exception.CustomException;
import com.joolun.common.utils.DateUtils;
import com.joolun.common.utils.SecurityUtils;
import com.joolun.common.utils.StringUtils;
import com.joolun.mall.entity.*;
import com.joolun.mall.mapper.ChainOrderMapper;
import com.joolun.mall.mapper.ChainPlanMapper;
import com.joolun.mall.mapper.SkuBasicMapper;
import com.joolun.mall.service.IChainDetailService;
import com.joolun.mall.service.IChainPlanService;
import com.joolun.mall.service.IChainService;
import com.joolun.mall.util.WxUtil;
import com.joolun.system.mapper.SysNumberSegmentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 品牌Service业务层处理
 * 
 * @author www.joolun.com
 * @date 2025-05-20
 */
@Service
public class ChainPlanServiceImpl extends ServiceImpl<ChainPlanMapper, ChainPlan> implements IChainPlanService
{

    @Autowired
    private IChainService chainService;

    @Autowired
    private IChainDetailService chainDetailService;

    @Autowired
    private ChainPlanMapper chainPlanMapper;

    @Autowired
    private ChainOrderMapper orderMapper;

    @Autowired
    private SysNumberSegmentMapper segmentMapper;

    @Autowired
    private SkuBasicMapper skuBasicMapper;

    @Override
    public List<Long> userChains(Long planId, String userId) {
        List<Chain> chains = chainService.list(
                Wrappers.query(new Chain()).lambda()
                        .eq(Chain::getDelFlag, "0")
                        .in(Chain::getPlanId, planId)

        );

        List<Long> chainIds = chains.stream().map(Chain::getId).collect(Collectors.toList());
        List<Long> returnChainIds = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(chainIds)){
            List<ChainOrder> chainOrders = orderMapper.selectList(
                    Wrappers.<ChainOrder>query().lambda()
                            .in(ChainOrder::getUserId, userId)
                            .in(ChainOrder::getChainId, chainIds)
                            .eq(ChainOrder::getDelFlag, "0")
                            .eq(ChainOrder::getStatus, "0")
            );
            returnChainIds = chainOrders.stream().map(ChainOrder::getChainId).collect(Collectors.toList());
        }

        return returnChainIds;
    }



    @Override
    public String getWxMsg(Long planId) {
        ChainPlan chainPlan = this.detail(planId);
        List<Chain> chains = chainPlan.getChains();
        //按时间排序
        chains.sort(Comparator.comparing(Chain::getBeginDate));
        StringBuilder msg = new StringBuilder();
        if(CollectionUtil.isNotEmpty(chains)){
            Optional<Date> startTime = chains.stream().filter(e -> Objects.nonNull(e.getBeginDate())).map(Chain::getBeginDate).min(Date::compareTo);
            String planStartTime = DateUtils.parseDateToStr("MM月dd日", startTime.get());
            msg.append(String.format("群内接龙%s%s%s开始", planStartTime,DateUtils.getChineseDay(LocalDate.now()),  DateUtils.parseDateToStr("HH:mm", startTime.get())));

            for (int i = 0; i < chains.size(); i++) {
                if(i==0){
                    msg.append("\n");
                }
                //yyyy-MM-dd HH:mm:ss
                Chain chain = chains.get(i);
                String chainStartTime = DateUtils.parseDateToStr("HH:mm", chain.getBeginDate());
                msg.append("\n").append(String.format("%s【%s】%s", chainStartTime, chain.getName(), StringUtils.trim(chain.getWxLink())));
            }
        }
        return msg.toString();
    }


    @Override
    public boolean add(ChainPlan dto) {
        dto.setCode(segmentMapper.makePlanNo());
        dto.setCreateBy(SecurityUtils.getUsername());
        dto.setCreateTime(new Date());
        int count = chainPlanMapper.insert(dto);
        dto.setWxLink(genLink(dto));
        chainPlanMapper.updateById(dto);
        return count > 0;
    }

    @Override
    public Page<ChainPlan> page1(Page<ChainPlan> page, ChainPlan dto){
        return chainPlanMapper.page1(page, dto);
    }

    @Override
    public ChainPlan detail(Long planId) {
        ChainPlan plan = this.getById(planId);
        if(Objects.isNull(plan)){
            throw new CustomException("数据不存在");
        }
        List<Chain> chains = chainService.list(
                Wrappers.query(new Chain()).lambda()
                        .eq(Chain::getDelFlag, "0")
                        .in(Chain::getPlanId, planId)
        );
        plan.setChains(chains);
        plan.setChainCount(chains.size());
        plan.setSpuCount(0);

        dealPlanState(chains, plan);
        List<Long> chainIds = chains.stream().map(Chain::getId).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(chainIds)){
            List<ChainDetail> chainDetails = chainDetailService.list(
                    Wrappers.query(new ChainDetail()).lambda().in(ChainDetail::getChainId, chainIds).eq(ChainDetail::getDelFlag, "0")
            );

            //处理排序
//            addSizeSort(chainDetails);

            Map<Long, List<ChainDetail>> chainDetailsMap = chainDetails.stream().collect(Collectors.groupingBy(ChainDetail::getChainId));
            chains.forEach(e -> {
                e.setDetails(chainDetailsMap.get(e.getId()));
                dealLinkState(e);
            });
            plan.setSpuCount(chainDetails.stream().collect(Collectors.groupingBy(ChainDetail::getSpuCode)).size());
        }
        return plan;
    }

    private void dealPlanState(List<Chain> chains, ChainPlan plan) {
        Date minDate = chains.stream().filter(e -> Objects.nonNull(e.getBeginDate())).map(Chain::getBeginDate).min(Date::compareTo).orElse(null);
        Date maxDate = chains.stream().filter(e -> Objects.nonNull(e.getEndDate())).map(Chain::getEndDate).max(Date::compareTo).orElse(null);
        plan.setPlanBeginDate(minDate);
        plan.setPlanEndDate(maxDate);
        if(CollectionUtil.isEmpty(chains) || Objects.isNull(minDate) || Objects.isNull(maxDate)){
            plan.setPlanState(0);
        }
        else if(maxDate.before(new Date())){
            plan.setPlanState(20);
        }
        else if(minDate.after(new Date())){
            plan.setPlanState(0);
        }else{
            plan.setPlanState(10);
        }
    }

    private void dealLinkState(Chain chain) {
        if(chain.getEndDate().before(new Date())){
            chain.setLinkState(20);
        }
        else if(chain.getBeginDate().after(new Date())){
            chain.setLinkState(0);
        }else{
            chain.setLinkState(10);
        }
    }

//    private void addSizeSort(List<ChainDetail> chainDetails) {
//        List<Long> skuIds = chainDetails.stream().map(ChainDetail::getSkuId).distinct().collect(Collectors.toList());
//        List<SkuBasic> skuBasics = skuBasicMapper.selectList(
//                Wrappers.query(new SkuBasic()).lambda()
//                        .eq(SkuBasic::getIsDelete, "0")
//                        .in(SkuBasic::getSkuId, skuIds)
//        );
//
//        Map<Integer, Integer> skuSortMap = skuBasics.stream()
//                .collect(Collectors.toMap(
//                        SkuBasic::getSkuId,
//                        SkuBasic::getSort,
//                        (existing, replacement) -> existing
//                ));
//        chainDetails.forEach(chainDetail -> {
//            Integer sizeSort = skuSortMap.get(chainDetail.getSkuId().intValue());
//            chainDetail.setSizeSort(Objects.isNull(sizeSort) ? 0 : sizeSort);
//        });
//    }

    public String genLink(ChainPlan plan) {
        GenerateShortLinkRequest shortLinkRequest = GenerateShortLinkRequest.builder()
                .pageUrl("pages/goods/linkList?id=" + plan.getId())
//                .pageUrl("pages/goods/linkDetail")
//                .pageTitle(chain.getName())
                .isPermanent(false)
                .build();
        return WxUtil.genLink(shortLinkRequest);
    }
}
